package com.runa.protocol.util;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by 龙
 * on 2019/03/04.
 */
public class UtilTime {

    private static Calendar calendar = Calendar.getInstance();

    /**
     * 获取当前时间
     *
     * @param formatStr 需要格式的目标字符串
     * @return
     */
    public static String getCurrentTime(String formatStr) {
        DateFormat sdf = new SimpleDateFormat(formatStr);
        return sdf.format(new Date());

    }

    /**
     * 将日期增加几小时
     *
     * @param date
     * @param hour
     * @return
     */
    public static Timestamp addHour(Date date, int hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, hour);
        return new Timestamp(calendar.getTimeInMillis());
    }

    /**
     * 字符串转换到时间格式 add 2014.4.14
     *
     * @param dateStr   需要转换的字符串
     * @param formatStr 需要格式的目标字符串 举例 yyyy-MM-dd
     * @return Date 返回转换后的时间
     * @throws ParseException 转换异常
     */
    public static Date StringToDate(String dateStr, String formatStr) {
        DateFormat sdf = new SimpleDateFormat(formatStr);
        Date date = null;
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            
        }
        return date;
    }

    /**
     * Date转成String shabangle
     *
     * @param format "yyyy-MM-dd"
     * @return
     */
    public static String dateToString(Date date, String format) {
        DateFormat dateFormat = new SimpleDateFormat(format);

        return dateFormat.format(date);
    }


    /**
     * 将日期增加或减去几月
     * 返回DATE类型
     *
     * @param date
     * @param month
     * @return
     * @throws ParseException
     */
    public static Date addOrSubtractMonth(Date date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        return new Date(calendar.getTimeInMillis());
    }

    /**
     * 将日期增加或减去几秒
     * 返回DATE类型
     *
     * @param date
     * @param second
     * @return
     */
    public static Date addOrSubtractSec(Date date, int second) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, second);
        return new Date(calendar.getTimeInMillis());
    }

    /**
     * 获取某年某月的最后一天
     *
     * @param year
     * @param month
     * @return
     */
    public static String getLastDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DATE));
        return new SimpleDateFormat("yyyy-MM-dd ").format(cal.getTime());
    }

    /**
     * 将日期加（或减）几天
     *
     * @param date
     * @param amount
     * @return
     */
    public static Date addOrSubDays(Date date, int amount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, amount);
        return new Date(calendar.getTimeInMillis());
    }

    /**
     * 计算两个日期之间相隔的天数
     *
     * @param begin
     * @param end
     * @return
     * @throws ParseException
     */
    public static long countDay(String begin, String end) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date beginDate, endDate;
        long day = 0;
        try {
            beginDate = format.parse(begin);
            endDate = format.parse(end);
            day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);
        } catch (ParseException e) {
            
        }
        return day;
    }

    /**
     * 将日期加（或减）几
     *
     * @param amount
     * @return
     * @throws ParseException
     */
    public static String addSomeTimes(Date nowdate, int amount,
                                      int calendarType, String format) {
        Calendar calendar = Calendar.getInstance();
        DateFormat simpleDateFormat = new SimpleDateFormat(format);
        try {
            calendar.setTime(nowdate);
            calendar.add(calendarType, amount);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        String dateStr = simpleDateFormat.format(calendar.getTime());

        return dateStr;
    }

    /****
     * 求两个日期间月份,天,小时集合
     *
     * @param startDateStr
     *            开始时间
     * @param endDateStr
     *            结束时间
     * @param type
     *            类型: 1：月份,2:天,3:小时,4:天(显示格式02-04 二月四号,只有月和日),5:天(显示格式:03,
     *            月份已经限定在一个月,只显示今天是几号)
     * @return
     * @throws ParseException
     */
    public static List<String> getBetweenTwoDateList(String startDateStr,
                                                     String endDateStr, int type) throws ParseException {
        List<String> list = new LinkedList<String>();
        DateFormat simpleDateFormat;
        Date startDate;
        Date endDate;
        try {
            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            startDate = simpleDateFormat.parse(startDateStr); // 开始日期
            endDate = simpleDateFormat.parse(endDateStr); // 结束日期
        } catch (Exception ex) {
            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            startDate = simpleDateFormat.parse(startDateStr); // 开始日期
            endDate = simpleDateFormat.parse(endDateStr); // 结束日期
        }

        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        startCalendar.setTime(startDate);
        endCalendar.setTime(endDate);
        String result = null;
        while (startCalendar.compareTo(endCalendar) <= 0) {
            startDate = startCalendar.getTime();
            switch (type) {

                case 0:
                    result = new SimpleDateFormat("yyyy-MM-dd 00:00:00")
                            .format(startDate);
                    result = result.substring(0, result.length());
                    list.add(result);
                    // 开始日期加一个天直到等于结束日期为止
                    startCalendar.add(Calendar.DAY_OF_MONTH, 1);
                    break;
                case 1:
                    result = new SimpleDateFormat("yyyy-MM").format(startDate);
                    result = result.substring(0, result.length());
                    list.add(result);
                    // 开始日期加一个月直到等于结束日期为止
                    startCalendar.add(Calendar.MONTH, 1);
                    break;
                case 2:
                    result = new SimpleDateFormat("yyyy-MM-dd").format(startDate);
                    result = result.substring(0, result.length());
                    list.add(result);
                    // 开始日期加一个天直到等于结束日期为止
                    startCalendar.add(Calendar.DAY_OF_MONTH, 1);
                    break;
                case 4:
                    result = new SimpleDateFormat("MM-dd").format(startDate);
                    result = result.substring(0, result.length());
                    list.add(result);
                    // 开始日期加一个天直到等于结束日期为止
                    startCalendar.add(Calendar.DAY_OF_MONTH, 1);
                    break;
                case 5:
                    result = new SimpleDateFormat("dd").format(startDate);
                    result = result.substring(0, result.length());
                    list.add(result);
                    // 开始日期加一个天直到等于结束日期为止
                    startCalendar.add(Calendar.DAY_OF_MONTH, 1);
                    break;
                default:
                    result = new SimpleDateFormat("yyyy-MM-dd HH")
                            .format(startDate);
                    result = result.substring(0, result.length());
                    list.add(result);
                    // 开始日期加一个月直到等于结束日期为止
                    startCalendar.add(Calendar.HOUR, 1);
                    break;
            }
        }
        return list;
    }

    /**
     * 将日期加（或减）几天
     *
     * @param date
     * @param amount
     * @return
     * @throws ParseException
     */
    public static String addSomeDays(String date, int amount) {
        Calendar calendar = Calendar.getInstance();
        DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date dateformat = simpleDateFormat.parse(date);
            calendar.setTime(dateformat);
            calendar.add(Calendar.DATE, amount);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        String dateStr = simpleDateFormat.format(calendar.getTime());

        return dateStr;
    }

    public static Date addMinute(Date date, int minute) {
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minute);
        return calendar.getTime();
    }

    /**
     * 获取日期对应周几
     *
     * @param date
     * @return
     */
    public static int getWeek(Date date) {
        calendar.setTime(date);
        int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (week == 0) week = 7;
        return week;
    }

    public static int getDayMonth(Date date) {
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    public static long countMinute(Date beginDate, Date endDate) {
        return (endDate.getTime() - beginDate.getTime()) / (60 * 1000);
    }

    /**
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 根据周分组
     */
    public static List<String> groupByWeek(String startTime, String endTime) {
        List<String> weekList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date startDate = UtilTime.StringToDate(startTime, "yyyy-MM-dd");
        Date endDate = UtilTime.StringToDate(endTime, "yyyy-MM-dd");

        Calendar cl1 = Calendar.getInstance();
        cl1.setTime(startDate);
        Calendar cl2 = Calendar.getInstance();
        cl2.setTime(endDate);
        Calendar cl3 = Calendar.getInstance();
        //判断起始日期为周几
        if (cl1.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            weekList.add(startTime);
        } else {
            cl1.add(Calendar.DAY_OF_MONTH, 8 - cl1.get(Calendar.DAY_OF_WEEK));
            weekList.add(startTime + "~" + sdf.format(cl1.getTime()));
        }
        do {
            cl1.add(Calendar.DAY_OF_MONTH, 1);
            String s = sdf.format(cl1.getTime());
            cl1.add(Calendar.DAY_OF_MONTH, 6);
            weekList.add(s + "~" + sdf.format(cl1.getTime()));
            cl3.setTime(cl1.getTime());
            cl3.add(Calendar.DAY_OF_MONTH, 7);
        } while (cl3.getTime().getTime() < cl2.getTime().getTime());
        cl1.add(Calendar.DAY_OF_MONTH, 1);
        String s = sdf.format(cl1.getTime());
        if (s.equals(endTime)) {
            weekList.add(s);
        } else {
            weekList.add(s + "~" + endTime);
        }
        return weekList;
    }

    /**
     * 获取两个时间中间的所有天
     */
    public static List<String> getBetweenTwoDayDateList(Date startDate, Date endDate) {
        List<String> list = new LinkedList<String>();
        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        startCalendar.setTime(startDate);
        endCalendar.setTime(endDate);
        String result = null;
        while (startCalendar.compareTo(endCalendar) <= 0) {
            startDate = startCalendar.getTime();
            result = new SimpleDateFormat("yyyy-MM-dd").format(startDate);
            list.add(result);
            // 开始日期加一个天直到等于结束日期为止
            startCalendar.add(Calendar.DAY_OF_MONTH, 1);
        }
        return list;
    }
}
